package cn.iocoder.yudao.module.wms.service.distribution;

import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.date.LocalDateTimeUtil;
import cn.hutool.core.stream.CollectorUtil;
import cn.hutool.core.util.StrUtil;
import cn.iocoder.yudao.module.wms.dal.dataobject.driver.DriverDO;
import cn.iocoder.yudao.module.wms.dal.dataobject.vehicle.VehicleDO;
import cn.iocoder.yudao.module.wms.enums.DistributionStatusEnum;
import cn.iocoder.yudao.module.wms.service.driver.DriverService;
import cn.iocoder.yudao.module.wms.service.vehicle.VehicleService;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import org.springframework.stereotype.Service;
import jakarta.annotation.Resource;
import org.springframework.validation.annotation.Validated;
import org.springframework.transaction.annotation.Transactional;

import java.time.LocalDateTime;
import java.util.*;
import cn.iocoder.yudao.module.wms.controller.admin.distribution.vo.*;
import cn.iocoder.yudao.module.wms.dal.dataobject.distribution.DistributionDO;
import cn.iocoder.yudao.framework.common.pojo.PageResult;
import cn.iocoder.yudao.framework.common.pojo.PageParam;
import cn.iocoder.yudao.framework.common.util.object.BeanUtils;

import cn.iocoder.yudao.module.wms.dal.mysql.distribution.DistributionMapper;

import static cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil.exception;
import static cn.iocoder.yudao.module.wms.enums.ErrorCodeConstants.*;

/**
 * 配送 Service 实现类
 *
 * @author 芋道源码
 */
@Service
@Validated
public class DistributionServiceImpl extends ServiceImpl<DistributionMapper, DistributionDO> implements DistributionService {

    @Resource
    private DistributionMapper distributionMapper;
    @Resource
    private DriverService driverService;
    @Resource
    private VehicleService  vehicleService;

    @Transactional(rollbackFor = Exception.class)
    @Override
    public String createDistribution(DistributionSaveReqVO reqVO) {
        // 查询驾驶人是否存在
        DriverDO driverDO = driverService.getDriver(reqVO.getDid());
        if (driverDO == null) {
            throw exception(DRIVER_NOT_EXISTS);
        }

        // 查询车辆是否存在
        VehicleDO vehicleDO = vehicleService.getVehicle(reqVO.getVid());
        if (vehicleDO == null) {
            throw exception(VEHICLE_NOT_EXISTS);
        }

        // 插入
        DistributionDO distributionDO = BeanUtils.toBean(reqVO, DistributionDO.class);
        String now = LocalDateTimeUtil.formatNormal(LocalDateTime.now());
        distributionDO.setId(UUID.randomUUID().toString())
                .setDriver(driverDO.getName())
                .setNumber(vehicleDO.getNumber())
                .setStatus(DistributionStatusEnum.WAIT_AUDIT.getCode())
                .setCreateAt(now)
                .setUpdateAt(now);
        distributionMapper.insert(distributionDO);
        // 返回
        return distributionDO.getId();
    }

    @Override
    public void updateDistribution(DistributionSaveReqVO reqVO) {
        // 校验存在
        DistributionDO distributionDO = validateDistributionExists(reqVO.getId());
        // 限制只有配送状态为等待审核时，才能编辑
        if (!DistributionStatusEnum.WAIT_AUDIT.getCode().equals(distributionDO.getStatus())) {
            throw exception(DISTRIBUTION_STATUS_INCORRECT);
        }
        // 更新
        DistributionDO updateObj = BeanUtils.toBean(reqVO, DistributionDO.class);
        updateObj.setUpdateAt(LocalDateTimeUtil.formatNormal(LocalDateTime.now()));
        distributionMapper.updateById(updateObj);
    }

    @Override
    public void deleteDistribution(String id) {
        // 校验存在
        validateDistributionExists(id);
        // 删除
        distributionMapper.deleteById(id);
    }

    private DistributionDO validateDistributionExists(String id) {
        DistributionDO distributionDO = distributionMapper.selectById(id);
        if (distributionDO == null) {
            throw exception(DISTRIBUTION_NOT_EXISTS);
        }
        return distributionDO;
    }

    @Override
    public DistributionDO getDistribution(String id) {
        return distributionMapper.selectById(id);
    }

    @Override
    public PageResult<DistributionDO> getDistributionPage(DistributionPageReqVO reqVO) {
        return distributionMapper.selectPage(reqVO);
    }

    @Override
    public PageResult<DistributionRespVO> getDistributionPage2(DistributionPageReqVO reqVO) {
        PageResult<DistributionDO> pageResult = distributionMapper.selectPage(reqVO);
        List<DistributionRespVO> respVOList = new ArrayList<>();
        if (pageResult != null && CollUtil.isNotEmpty(pageResult.getList())) {
            respVOList = BeanUtils.toBean(pageResult.getList(), DistributionRespVO.class);
            respVOList.stream()
                    // 设置属性
                    .peek(o -> o.setStatusDesc(DistributionStatusEnum.getDescByCode(o.getStatus())))
                    .toList();
        }
        return new PageResult<DistributionRespVO>()
                .setTotal(pageResult.getTotal())
                .setList(respVOList);
    }

    @Override
    public void confirmAudit(String id) {
        // 配送状态0更新为1
        // 校验原配送状态是否为0
        DistributionDO distributionDO = this.getById(id);
        if(distributionDO == null) {
            throw exception(DISTRIBUTION_NOT_EXISTS);
        }
        if (!DistributionStatusEnum.WAIT_AUDIT.getCode().equals(distributionDO.getStatus())) {
            throw exception(DISTRIBUTION_STATUS_INCORRECT);
        }

        this.updateById(
                new DistributionDO()
                        .setId(id)
                        .setStatus(DistributionStatusEnum.TRANSIT.getCode())
                        .setUpdateAt(LocalDateTimeUtil.formatNormal(LocalDateTime.now()))
        );
    }

    @Override
    public void confirmOk(String id) {
        // 配送状态1更新为2
        // 校验原配送状态是否为1
        DistributionDO distributionDO = this.getById(id);
        if(distributionDO == null) {
            throw exception(DISTRIBUTION_NOT_EXISTS);
        }
        if (!DistributionStatusEnum.TRANSIT.getCode().equals(distributionDO.getStatus())) {
            throw exception(DISTRIBUTION_STATUS_INCORRECT);
        }

        this.updateById(
                new DistributionDO()
                        .setId(id)
                        .setStatus(DistributionStatusEnum.DISTRIBUTION_OK.getCode())
                        .setUpdateAt(LocalDateTimeUtil.formatNormal(LocalDateTime.now()))
        );
    }


}